package HTTP

import (
	"SQL/util"
	"logs"
	"fmt"
	"regexp"
	"unicode/utf8"
)

/*--------------------------基本checkout---------------------------------------*/
func checkOutId(id string) (bool, int, string) {

	info := "success"
	code := Success

	if id == "" {
		info = "From:checkOutId:--- id is invalid because id is null"
		return false, errInvalidID, info
	}

	//判断字符是否合法
	reg := regexp.MustCompile(`^[0-9]{5}$`)
	ok := reg.MatchString(id)
	if !ok {
		return false, errInvalidID, mInvalidObjectID
	}

	return true, code, info

}

func checkOutJsonInfo(jsonInfo string) (bool, int, string) {

	if jsonInfo == "" || jsonInfo == " " {
		return true, Success, "success"
	}
	//判断字符是否合法
	reg := regexp.MustCompile("^{.*\\r*\\n*}")
	ok := reg.MatchString(jsonInfo)
	if !ok {
		return false, errInvalidCustomInfo, mInvalidCustomInfo
	}
	return true, Success, "success"
}

func checkOutNickName(nickName string) (bool, int, string) {

	if utf8.RuneCountInString(nickName) > 200 {
		return false, errInvalidNickname, mInvalidNickname
	}
	return true, Success, "success"
}

func checkOutIcon(icon *string) bool {

	//如果为空 设置icon默认值
	if *icon == "" {
		*icon = "default Icon"
	}

	return true
}

func checkOutPassword(password string) (bool, int, string) {

	//判断密码长度是否过长
	if utf8.RuneCountInString(password) > 200 {
		return false, errPasswordWrong, mInvalidPassword
	}

	//判断字符是否合法
	reg := regexp.MustCompile("^[\\da-zA-Z-_\\.\\?\\!\\,\\@\\#\\$\\%\\^\\&\\*\\(\\)\\=\\+\\[\\]\\{\\}]{6,20}$")
	ok := reg.MatchString(password)
	if !ok {
		return false, errPasswordWrong, mInvalidPassword
	}

	return true, Success, "success"
}

/*--------------------------基本判定---------------------------------------*/
func isGroupMember(userID string, groupID string) (string, int, bool) {
	info := "success"
	code := Success
	ok := true

	ok, code, info = checkOutId(userID)
	if !ok {
		info = "From:isGroup---userID is invalid"
		return info, code, ok
	}
	ok, code, info = checkOutId(groupID)
	if !ok {
		info = "From:isGroup---groupID is invalid"
		return info, code, ok
	}

	info, code, ok = isGroup(groupID)
	if !ok {
		info = "From:isGroupMember.isGroup---isGroup is invalid because groupID is not group"
		return info, code, ok
	}

	info, code, ok = isUser(userID)
	if !ok {
		info = "From:isGroupMember.isObject---userID is invalid because userID is not object"
		return info, code, ok
	}

	sql := "select userid from members where groupid = $1"
	rows, err := util.Query(sql, groupID)
	defer rows.Close()
	if err != nil {
		if err != nil {
			logs.Print("From:isGroupMember.Query:---", err.Error())
			info = "From:isGroupMember.Query:---error"
			return info, errDBQueryFailed, false
		}
	}

	var memberID string
	for rows.Next() {
		err = rows.Scan(&memberID)
		if err != nil {
			logs.Print("From:isGroupMember.Scan:---", err.Error())
			info = "From:isGroupMember.Scan:---error"
			return info, errRowsScan, false
		}
		if memberID == userID {
			return info, code, true
		}
	}
	info = "From:isGroupMember.Scan:---userID is not the talkerID group member"
	return info, errInvalidID, false
}
func isGroup(id string) (string, int, bool) {
	info := "success"
	code := Success
	ok := true

	ok, code, info = checkOutId(id)
	if !ok {
		info = "From:isGroup---id is invalid"
		return info, code, ok
	}

	sql := "select isuser from objects where id = $1"

	rows, err := util.Query(sql, id)
	defer rows.Close()
	if err != nil {
		if err != nil {
			logs.Print("From:isGroup.Query", err.Error())
			info = "From:isGroup.Query---error"
			return info, errDBQueryFailed, false
		}
	}
	var isUser bool
	if rows.Next() {
		err = rows.Scan(&isUser)
		if err != nil {
			fmt.Println("From:isGroup.Scan", err.Error())
			info = "From:isGroup.Scan---error"
			return info, errRowsScan, false
		}
		if isUser {
			fmt.Println("From:isGroup:---id is invalid because id is not group")
			info = "From:isGroup:---id is invalid because id is not group"
			code = errInvalidID
			return info, code, false
		} else {
			return info, code, true
		}
	} else {
		info = "From:isGroup:---id is invalid because id is not object"
		code = errInvalidID
		return info, code, false

	}

	return info, code, true
}
func isObject(id string) (string, int, bool) {
	info := "success"
	code := Success
	ok := true

	ok, code, info = checkOutId(id)
	if !ok {
		info = "From:isObject:---id is invalid"
		return info, code, ok
	}

	sql := "select * from objects where id = $1"

	rows, err := util.Query(sql, id)
	defer rows.Close()
	if err != nil {
		logs.Print("From:alterObjectData.queryObject.Query:---", err.Error())
		info = "From:isObject.Query:---error"
		return info, errDBQueryFailed, false
	}

	if !rows.Next() {
		info = "From:isObject:---objectID is invalid because the objectID is no exist"
		return info, errInvalidID, false
	}

	return info, Success, true
}
func isManager(id string) (string, int, bool) {

	info := "success"
	code := Success
	ok := true

	ok, code, info = checkOutId(id)
	if !ok {
		info = "From:isGroup:---id is invalid"
		return info, code, ok
	}

	sql := "select ismanager from users where id =$1"
	rows, err := util.Query(sql, id)
	if err != nil {
		info = "From:isGroup.rows.Query:---error"
		return info, errDBQueryFailed, false
	}
	defer rows.Close()
	var ismanager bool
	if !rows.Next() {
		info = "From:isGroup.rows.Next:---id is invalid because id is not user"
		return info, errDBQueryFailed, false
	}
	err = rows.Scan(&ismanager)

	if !ismanager {
		info = "From:isGroup.rows.Next:---id is invalid because id is not a managerID"
		return info, errInvalidID, false
	}
	return info, Success, true
}
func isUser(id string) (string, int, bool) {
	info := "success"
	code := Success
	ok := true

	ok, code, info = checkOutId(id)
	if !ok {
		info = "From:isUser:---id is invalid"
		return info, code, ok
	}

	sql := "select isuser from objects where id = $1"

	rows, err := util.Query(sql, id)
	defer rows.Close()
	if err != nil {
		if err != nil {
			logs.Print("From:isUser.Query", err.Error())
			info = "From:isUser.Query:---error"
			return info, errDBQueryFailed, false
		}
	}
	var isUser bool
	if rows.Next() {
		err = rows.Scan(&isUser)
		if err != nil {
			logs.Print("From:isUser.Scan", err.Error())
			info = "From:isUser.Scan:---error"
			return info, errRowsScan, false
		}
		if isUser {
			return info, code, true
		} else {
			info = "From:isUser:---id is invalid because id is not user"
			code = errInvalidID
			return info, code, false
		}
	} else {
		info = "From:isUser:---id is invalid because id is not object"
		code = errInvalidID
		return info, code, false

	}

	return info, code, true
}
